#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>

#define EXTERNAL_CONFIG_FILE "3g_dongle.cfg"
/* external configuration operator dial number */               
#define DIAL_NUMBER_LEN 35                                    
#define DIAL_NUMBER_SECTION     "DIAL_NUMBER"               
#define WCDMA_OPERATOR_DIAL     "wcdma"                                       
#define CDMA2000_OPERATOR_DIAL  "cdma2000"
#define TDSCDMA_OPERATOR_DIAL   "tdscdma"
                                               
/* external configuration modem table keywords */
#define  DONGLE_NAME        "dongle_name"
#define  PRODUCTION_NAME    "production_name"
#define  VENDOR_NAME        "vendor_name"
#define  NETWORK_TYPE       "network"       
#define  PID_VID_ORIGIN     "pid_vid_origin"        
#define  BCDDEVICE_ORIGIN   "bcdDevice_origin"                     
#define  PID_VID_NOW        "pid_vid_now"                              
#define  BCDDEVICE_NOW      "bcdDevice_now"            
#define  AT_PORT            "at_port"
#define  PPP_PORT           "ppp_port"      
#define  DIAL_OPERATOR      "dial_operator"

#define min( x, y )                     ( (x) < (y) ? (x) : (y) )

static char *readLine(char *line, int n, FILE *stream)
{
    static   char*   rs;

    rs   =   fgets(line, n, stream);
    if(strlen(line) >= 1) {
        //½«Ò»ÐÐ×îºóµÄ»»ÐÐ×Ö·ûÈ¥µô
        if(line[strlen(line) - 1] == 0xa)
            line[strlen(line) - 1] = line[strlen(line)];
    }
    return   rs;
}

/*
    return 1 if equal to '#' at the very beginning of the line.
*/
static int isCommentStr(char *line)
{
    int len=0, pos=0;

    if(line[0] == '#')
        return 1;
    return 0;
}

/*
    return 1  if equal to '[]'
*/
static int isSectionLine(char *line)
{
    if(line == NULL) return 0;
    if(strchr(line, '[') && strchr(line, ']'))
        return 1;
    return 0;
}

/*
    return 1 if equal to '='
*/
static int isIdString(char *line)
{
    if(line == NULL) return 0;
    if(strchr(line, '='))
        return 1;
    return 0;
}
static int getIdAndString(char *line, char *id_value, char *string_value)
{
    int i = 0;
    char *tmp;

    if((line == NULL) || (id_value == NULL)
         || (string_value == NULL)) {
        printf("getIdAndString error : NULL parameter!\n");
        return -1;
    }

    tmp = strchr(line, '=');
    memcpy(id_value, line, tmp - line);
    id_value[tmp-line] = '\0';

    if(++tmp == NULL)
        return -1;

    memcpy(string_value, tmp, strlen(line) - (tmp - line));
    string_value[strlen(line) - (tmp - line)] = '\0';

    return 0;
}

static int getSectionString(char *line, char *section, int len)
{
    char *tmp, *tmp_end;
    int start = 0;
    int end = 0;
    int i = 0;
    int section_length = 0;

    if(line == NULL)
        return -1;

    memset(section, 0 , len);
    tmp  = strchr(line, '[');
    tmp_end = strrchr(line, ']');

    tmp++;

    memcpy(section,tmp,tmp_end - tmp);
    section[tmp_end - tmp] = '\0';

    return 0;
}
static int insertDataNode(char *id_value, char *string_value)                 
{
    char *end;
	if(!strncmp(id_value,DONGLE_NAME,min(strlen(id_value),strlen(DONGLE_NAME))))    {
		printf("{\"%s\", ", string_value); 
	} else if(!strncmp(id_value,PRODUCTION_NAME, min(strlen(id_value), strlen(PRODUCTION_NAME))))   {
		printf("\"%s\", ", string_value); 
	} else if(!strncmp(id_value,VENDOR_NAME,min(strlen(id_value), strlen(VENDOR_NAME))))    {
		printf("\"%s\", ", string_value); 
	}else if(!strncmp(id_value,NETWORK_TYPE,min(strlen(id_value), strlen(NETWORK_TYPE)))) {
		printf("%s, ", string_value); 
	}else if(!strncmp(id_value,PID_VID_ORIGIN,min(strlen(id_value),strlen(PID_VID_ORIGIN)))) {
		printf("0x%lx, ", strtoul(string_value,&end,16)); 
	}else if(!strncmp(id_value,BCDDEVICE_ORIGIN,min(strlen(id_value),strlen(BCDDEVICE_ORIGIN)))) {
		printf("0x%lx, ", strtoul(string_value,&end,16)); 
	}else if(!strncmp(id_value,PID_VID_NOW,min(strlen(id_value),strlen(PID_VID_NOW)))) {
		printf("0x%lx, ", strtoul(string_value,&end,16)); 
	}else if(!strncmp(id_value,BCDDEVICE_NOW,min(strlen(id_value),strlen(BCDDEVICE_NOW)))) {
		printf("0x%lx, ", strtoul(string_value,&end,16)); 
	}else if(!strncmp(id_value,AT_PORT,min(strlen(id_value),strlen(AT_PORT)))) {
		printf("%ld, ", strtoul(string_value,&end,10)); 
	}else if(!strncmp(id_value,PPP_PORT,min(strlen(id_value),strlen(PPP_PORT)))) {
		printf("%ld},\n", strtoul(string_value,&end,10)); 
	}

	return 0;
}


static int loadIniFile()
{
    FILE *file = NULL;
    char line_buf[128] = {0};
    char section_buf[64] = {0};
    char id_buf[64] = {0};
    char string_buf[128] = {0};
    int ret = 0;
    char *char_tmp = line_buf;

    /* open the file */
    file = fopen(EXTERNAL_CONFIG_FILE, "r");
    if(file == NULL) {
        printf("open file failed(%s)\n", EXTERNAL_CONFIG_FILE);
        return -1;
    }

    while(!feof(file)){

        if(readLine(line_buf, 100, file) == NULL) {
            fclose(file);
            file = NULL;
            //printf("read file end.\n");
            return 0;
        }

        /*find the section*/
        // not section or id,continue
        if((strlen(line_buf) < 2) || (isCommentStr(line_buf) == 1))
            continue;
        if((isSectionLine(line_buf) != 1)&&(isIdString(line_buf) != 1))
            continue;
        if(isSectionLine(line_buf) == 1) {
            //printf("Find a line which have a section mark(%s)\n", line_buf);
            getSectionString(line_buf, section_buf, 64);
            //printf("getSectionString section(%s)\n", section_buf);
            if(strlen(section_buf) > 0) {
                //ignore section DIAL_NUMBER
                if(!strncmp(section_buf, DIAL_NUMBER_SECTION, min(strlen(section_buf), strlen(DIAL_NUMBER_SECTION)))) {
                    continue;
                }
            }
        }
        /*find the id value*/
        if(isIdString(line_buf) == 1) {
            memset(id_buf,0,sizeof(id_buf));
            memset(string_buf,0,sizeof(string_buf));
            if(getIdAndString(line_buf, id_buf, string_buf) == 0) {
                if((strlen(id_buf) > 0)  && (strlen(string_buf) > 0)) {
                    //printf("insertDataNode %s %s\n", id_buf, string_buf);
					insertDataNode(id_buf, string_buf);
                } else {
                    printf("parse file err.");
                    ret = -1;
                    goto error;
                }
            }
        }

    }

error:
    fclose(file);
    file = NULL;
    return ret;
}

int main(int argc, char** argv)
{
	loadIniFile();
	return 0;
}
